home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / omega / ospell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-06  |  16.1 KB  |  785 lines

  1. /* omega copyright (C) by Laurence Raphael Brothers, 1987,1988 */
  2. /* ospell.c */
  3. /* functions having to do with spellcasting */
  4.  
  5. #include "oglob.h"
  6.  
  7.  
  8. void s_wish()
  9. {
  10.   if (random_range(100) > Player.iq+Player.pow+Player.level) {
  11.     mprint("Your concentration is flawed!");
  12.     mprint("The spell energy backfires!");
  13.     p_damage(random_range(Spells[S_WISH].powerdrain),
  14.          UNSTOPPABLE,
  15.          "a backfired wish spell");
  16.   }
  17.   else {
  18.     wish(0);
  19.     mprint("The power of the spell is too much for you to withstand!");
  20.     mprint("All memory of the spell is expunged from your brain.");
  21.     Spells[S_WISH].known = FALSE;
  22.   }
  23. }
  24.  
  25. void s_firebolt()
  26. {
  27.   int x=Player.x,y=Player.y;
  28.   setspot(&x,&y);
  29.   fbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*10+10);
  30. }
  31.  
  32. void s_missile()
  33. {
  34.   int x=Player.x,y=Player.y;
  35.   setspot(&x,&y);
  36.   nbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*3+3);
  37. }
  38.  
  39. void s_teleport()
  40. {
  41.   p_teleport(0);
  42. }
  43.  
  44. void s_disrupt()
  45. {
  46.   int x=Player.x,y=Player.y;
  47.   setspot(&x,&y);
  48.   disrupt(x,y,Player.level*10+25);
  49. }
  50.  
  51.  
  52. void s_disintegrate()
  53. {
  54.   int x=Player.x,y=Player.y;
  55.   setspot(&x,&y);
  56.   disintegrate(x,y);
  57. }
  58.  
  59.  
  60. void s_sleep()
  61. {
  62.   sleep_monster(0);
  63. }
  64.  
  65. void s_heal()
  66. {
  67.   heal(3);
  68. }
  69.  
  70. void s_dispel()
  71. {
  72.   dispel((Player.level+Player.maxpow)/10); 
  73. }
  74.  
  75. void s_breathe()
  76. {
  77.   breathe(0);
  78. }
  79.  
  80. void s_invisible()
  81. {
  82.   invisible(0);
  83. }
  84.  
  85.  
  86. void s_warp()
  87. {
  88.   warp(1);
  89. }
  90.  
  91. void s_enchant()
  92. {
  93.   enchant(1);
  94. }
  95.  
  96.  
  97. void s_bless()
  98. {
  99.   bless(0);
  100. }
  101.  
  102.  
  103. void s_restore()
  104. {
  105.   recover_stat(0);
  106. }
  107.  
  108.  
  109. void s_cure()
  110. {
  111.   cure(0);
  112. }
  113.  
  114.  
  115. void s_truesight()
  116. {
  117.   truesight(0);
  118. }
  119.  
  120.  
  121. void s_hellfire()
  122. {
  123.   int x=Player.x,y=Player.y;
  124.   setspot(&x,&y);
  125.   hellfire(x,y,0);
  126. }
  127.  
  128.  
  129. void s_knowledge()
  130. {
  131.   knowledge(0);
  132. }
  133.  
  134.  
  135. void s_hero()
  136. {
  137.   hero(0);
  138. }
  139.  
  140. /* spell takes longer and longer to work deeper into dungeon */
  141. void s_return()
  142. {
  143.   mprint("You hear a whine as your spell begins to charge up.");
  144.   Player.status[RETURNING] = 
  145.     ((Current_Environment == Current_Dungeon) ? difficulty() : 1);
  146. }
  147.  
  148. void s_desecrate()
  149. {
  150.   sanctify(-1);
  151. }
  152.  
  153.  
  154. void s_haste()
  155. {
  156.   haste(0);
  157. }
  158.  
  159.  
  160. void s_summon()
  161. {
  162.   summon(0,-1);
  163. }
  164.  
  165.  
  166. void s_sanctuary()
  167. {
  168.   sanctuary();
  169. }
  170.  
  171. void s_sanctify()
  172. {
  173.   sanctify(1);
  174. }
  175.  
  176.  
  177. void s_accuracy()
  178. {
  179.   accuracy(0);
  180. }
  181.  
  182. void s_fear()
  183. {
  184.   int x = Player.x,y=Player.y;
  185.   setspot(&x,&y);
  186.   inflict_fear(x,y);
  187. }
  188.  
  189.  
  190. /* Has all kinds of effects in different circumstances.
  191.    Eventually will be more interesting */
  192. void s_ritual()
  193. {
  194.   pob symbol;
  195.   int i,roomno;
  196.   mprint("You begin your ritual....");
  197.   mprint("You enter a deep trance. Time Passes...");
  198.   setgamestatus(SKIP_PLAYER);
  199.   time_clock(FALSE);
  200.   setgamestatus(SKIP_PLAYER);
  201.   time_clock(FALSE);
  202.   setgamestatus(SKIP_PLAYER);
  203.   time_clock(FALSE);
  204.   setgamestatus(SKIP_PLAYER);
  205.   time_clock(FALSE);
  206.   setgamestatus(SKIP_PLAYER);
  207.   time_clock(FALSE);
  208.   if (RitualHour == hour())
  209.     mprint("Your mental fatigue prevents from completing the ritual!");
  210.   else if (random_range(100) > Player.iq+Player.pow+Player.level)
  211.     mprint("Your concentration was broken -- the ritual fails!");
  212.   else {
  213.     mprint("You charge the ritual with magical energy and focus your will.");
  214.     mprint("Time Passes...");
  215.     setgamestatus(SKIP_PLAYER);
  216.     time_clock(FALSE);
  217.     setgamestatus(SKIP_PLAYER);
  218.     time_clock(FALSE);
  219.     setgamestatus(SKIP_PLAYER);
  220.     time_clock(FALSE);
  221.     setgamestatus(SKIP_PLAYER);
  222.     time_clock(FALSE);
  223.     setgamestatus(SKIP_PLAYER);
  224.     time_clock(FALSE);
  225.     RitualHour = hour();
  226.     /* set of random conditions for different ritual effects */
  227.     if (Current_Environment == E_CITY) {
  228.       mprint("Flowing waves of mystical light congeal all around you.");
  229.       mprint("'Like wow, man! Colors!'");
  230.       mprint("Appreciative citizens throw you spare change.");
  231.       Player.cash +=random_range(50);
  232.     }
  233.     else if ((roomno=Level->site[Player.x][Player.y].roomnumber) >= 0) {
  234.       if (RitualRoom == roomno)
  235.     mprint("For some reason the ritual doesn't work this time...");
  236.       else {
  237.     RitualRoom = roomno;
  238.     switch (RitualRoom) {
  239.     case ROOMBASE+9: /* ransacked treasure chamber */
  240.       mprint("Your spell sets off frenetic growth all around you!");
  241.       for(i=0;i<8;i++){
  242.         Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].locchar =
  243.           HEDGE;
  244.         Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].p_locf =
  245.           L_TRIFID;
  246.       }
  247.       break;
  248.     case ROOMBASE+22: /* boudoir */
  249.       mprint("A secret panel opens next to the bed....");
  250.       if (random_range(2))
  251.         summon(0,ML4+6); /* succubus/incubus */
  252.       else summon(0,ML4+7); /* satyr/nymph */
  253.       break;
  254.     case ROOMBASE+26: /*shrine to high magic */
  255.       mprint("A storm of mana coaelesces around you.");
  256.       mprint("You are buffeted by bursts of random magic.");
  257.       p_damage(random_range(Player.pow),UNSTOPPABLE,"high magic");
  258.       mprint("Continue ritual? Could be dangerous.... [yn] ");
  259.       if (ynq()=='y') s_wish();
  260.       else mprint("The mana fades away to nothingness.");
  261.       Level->site[Player.x][Player.y].roomnumber = RS_ZORCH;
  262.       break;
  263.     case ROOMBASE+27: /* magician's lab */
  264.       mprint("Your magical activity sets off a latent spell in the lab!");
  265.       cast_spell(random_range(NUMSPELLS));
  266.       break;
  267.     case ROOMBASE+28: /* pentagram room */
  268.       mprint("A smoky form begins to coalesce....");
  269.       summon(-1,-1);
  270.       mprint("Fortunately, it seems confined to the pentagram.");
  271.       m_status_reset(Level->mlist->m,MOBILE);
  272.       break;
  273.     case ROOMBASE+29: /* blue omega room */
  274.       mprint("The Lords of Destiny look upon you....");
  275.       if (Player.level > 10) {
  276.         mprint("A curtain of blue flames leaps up from the omega.");
  277.         mprint("Enter it? [yn] ");
  278.         if (ynq()=='y') l_adept();
  279.       }
  280.       else {
  281.         if (Player.patron == DESTINY) {
  282.           mprint("Your patrons take pity on you.");
  283.           if ((Player.rank[PRIESTHOOD]<SPRIEST) &&
  284.           (! find_item(&symbol,ARTIFACTID+19,-1))) {
  285.         symbol = ((pob) malloc(sizeof(objtype)));
  286.         *symbol = Objects[ARTIFACTID+19];
  287.         symbol->known = 2;
  288.         symbol->charge = 17;
  289.         gain_item(symbol);
  290.         mprint("You feel uplifted.");
  291.           }
  292.           else gain_experience(min(1000,Player.xp));
  293.         }
  294.         else if (random_range(3)==1) {
  295.           mprint("You feel Fated.");
  296.           gain_experience(Player.level*Player.level*10);
  297.           Player.hp = Player.maxhp;
  298.         }
  299.         else if (random_range(2)) {
  300.           mprint("You feel Doomed.");
  301.           Player.hp = 1;
  302.           Player.mana = 0;
  303.           Player.xp = 0;
  304.         }
  305.         else mprint("The Lords of Destiny laugh at you!");
  306.       }
  307.       break;
  308.     default:
  309.       mprint("Well, not much effect. Chalk it up to experience.");
  310.       gain_experience(Player.level*5);
  311.       break;
  312.     }
  313.       }
  314.     }
  315.     else {
  316.       if (RitualRoom == Level->site[Player.x][Player.y].roomnumber)
  317.     mprint("The ritual fails for some unexplainable reason.");
  318.       else {
  319.     mprint("The ritual seems to be generating some spell effect.");
  320.     RitualRoom = Level->site[Player.x][Player.y].roomnumber;
  321.     switch (RitualRoom) {
  322.     case RS_WALLSPACE:
  323.       shadowform();
  324.       break;
  325.     case RS_CORRIDOR:
  326.       haste(0);
  327.       break;
  328.     case RS_PONDS:
  329.       breathe(0);
  330.       break;
  331.     case RS_ADEPT:
  332.       hero(1);
  333.       break;
  334.     default:
  335.       mprint("The ritual doesn't seem to produce any tangible results...");
  336.       gain_experience(Player.level*6);
  337.     }
  338.       }
  339.     }
  340.   }
  341. }
  342.  
  343.  
  344.  
  345. void s_apport()
  346. {
  347.   apport(0);
  348. }
  349.  
  350. void s_shadowform()
  351. {
  352.   shadowform();
  353. }
  354.  
  355. void s_alert()
  356. {
  357.   alert(0);
  358. }
  359.  
  360. void s_regenerate()
  361. {
  362.   regenerate(0);
  363. }
  364.  
  365. void s_clairvoyance()
  366. {
  367.   clairvoyance(10);
  368. }
  369.  
  370. void s_drain()
  371. {
  372.   drain(0);
  373. }
  374.  
  375. void s_levitate()
  376. {
  377.   levitate(0);
  378. }
  379.  
  380. void s_polymorph()
  381. {
  382.   polymorph(0);
  383. }
  384.  
  385.  
  386. /* lball spell */
  387. void s_lball()
  388. {
  389.   int x=Player.x,y=Player.y;
  390.   setspot(&x,&y);
  391.   lball(Player.x,Player.y,x,y,Player.level*10+10);
  392. }
  393.  
  394. void s_identify()
  395. {
  396.   identify(0);
  397. }
  398.  
  399. void s_objdet()
  400. {
  401.   objdet(1);
  402. }
  403.  
  404. void s_mondet()
  405. {
  406.   mondet(1);
  407. }
  408.  
  409.  
  410. /* select a spell to cast */
  411. int getspell()
  412. {
  413.   int spell= -2;
  414.   do {
  415.     mprint("Cast Spell: [type spell abbrev, ?, or ESCAPE]: ");
  416.     spell = spellparse();
  417.   } while (spell < ABORT);
  418.   return(spell);
  419. }
  420.  
  421.  
  422. char *spellid(id)
  423. int id;
  424. {
  425.   switch(id) {
  426.     case S_MON_DET:return("monster detection");break;
  427.     case S_OBJ_DET:return("object detection");break;
  428.     case S_IDENTIFY:return("identification");break;
  429.     case S_FIREBOLT:return("firebolt");break;
  430.     case S_LBALL:return("ball lightning");break;
  431.     case S_SLEEP:return("sleep");break;
  432.     case S_DISRUPT:return("disrupt");break;
  433.     case S_DISINTEGRATE:return("disintegrate");break;
  434.     case S_TELEPORT:return("teleport");break;
  435.     case S_MISSILE:return("magic missile"); break;
  436.     case S_HEAL:return("healing"); break;
  437.     case S_DISPEL:return("dispelling"); break;
  438.     case S_BREATHE:return("breathing"); break;
  439.     case S_INVISIBLE:return("invisibility"); break;
  440.     case S_WARP:return("the warp"); break;
  441.     case S_ENCHANT:return("enchantment"); break;
  442.     case S_BLESS:return("blessing"); break;
  443.     case S_RESTORE:return("restoration"); break;
  444.     case S_CURE:return("curing"); break;
  445.     case S_TRUESIGHT:return("true sight"); break;
  446.     case S_HELLFIRE:return("hellfire"); break;
  447.     case S_KNOWLEDGE:return("self knowledge"); break;
  448.     case S_HERO:return("heroism"); break;
  449.     case S_RETURN:return("return"); break;
  450.     case S_DESECRATE:return("desecration"); break;
  451.     case S_HASTE:return("haste"); break;
  452.     case S_SUMMON:return("summoning"); break;
  453.     case S_SANCTUARY:return("sanctuary"); break;
  454.     case S_ACCURACY:return("accuracy"); break;
  455.     case S_RITUAL:return("ritual magic"); break;
  456.     case S_APPORT:return("apportation"); break;
  457.     case S_SHADOWFORM:return("shadow form"); break;
  458.     case S_ALERT:return("alertness"); break;
  459.     case S_REGENERATE:return("regeneration"); break;
  460.     case S_SANCTIFY:return("sanctification"); break;
  461.     case S_CLAIRVOYANCE:return("clairvoyance"); break;
  462.     case S_DRAIN:return("energy drain"); break;
  463.     case S_LEVITATE:return("levitate"); break;
  464.     case S_POLYMORPH:return("polymorph"); break;
  465.     case S_FEAR:return("fear"); break;
  466.     case S_WISH:return("wishing"); break;
  467.     default:return("???"); break;
  468.   }      
  469. }
  470.  
  471.  
  472.  
  473. void initspells()
  474. {
  475.   int i;
  476.  
  477.   for (i=0; i<NUMSPELLS; i++)
  478.     Spells[i].known = FALSE;
  479.  
  480.   Spells[S_MON_DET].powerdrain = 3;
  481.   Spells[S_MON_DET].id = S_MON_DET;
  482.  
  483.   Spells[S_OBJ_DET].powerdrain = 3;
  484.   Spells[S_OBJ_DET].id = S_OBJ_DET;
  485.  
  486.   Spells[S_IDENTIFY].powerdrain = 10;
  487.   Spells[S_IDENTIFY].id = S_IDENTIFY;
  488.  
  489.   Spells[S_FIREBOLT].powerdrain = 20;
  490.   Spells[S_FIREBOLT].id = S_FIREBOLT;
  491.  
  492.   Spells[S_SLEEP].powerdrain = 15;
  493.   Spells[S_SLEEP].id = S_SLEEP;
  494.  
  495.   Spells[S_LBALL].powerdrain = 25;
  496.   Spells[S_LBALL].id = S_LBALL;
  497.  
  498.   Spells[S_TELEPORT].powerdrain = 20;
  499.   Spells[S_TELEPORT].id = S_TELEPORT;
  500.  
  501.   Spells[S_DISRUPT].powerdrain = 30;
  502.   Spells[S_DISRUPT].id = S_DISRUPT;
  503.  
  504.   Spells[S_DISINTEGRATE].powerdrain = 40;
  505.   Spells[S_DISINTEGRATE].id = S_DISINTEGRATE;
  506.  
  507.   Spells[S_MISSILE].powerdrain = 10;
  508.   Spells[S_MISSILE].id = S_MISSILE;
  509.  
  510.   Spells[S_HEAL].powerdrain = 15;
  511.   Spells[S_HEAL].id = S_HEAL;
  512.  
  513.   Spells[S_DISPEL].powerdrain = 40;
  514.   Spells[S_DISPEL].id = S_DISPEL;
  515.  
  516.   Spells[S_BREATHE].powerdrain = 20;
  517.   Spells[S_BREATHE].id = S_BREATHE;
  518.  
  519.   Spells[S_INVISIBLE].powerdrain = 15;
  520.   Spells[S_INVISIBLE].id = S_INVISIBLE;
  521.  
  522.   Spells[S_WARP].powerdrain = 50;
  523.   Spells[S_WARP].id = S_WARP;
  524.  
  525.   Spells[S_ENCHANT].powerdrain = 30;
  526.   Spells[S_ENCHANT].id = S_ENCHANT;
  527.  
  528.   Spells[S_BLESS].powerdrain = 30;
  529.   Spells[S_BLESS].id = S_BLESS;
  530.  
  531.   Spells[S_RESTORE].powerdrain = 20;
  532.   Spells[S_RESTORE].id = S_RESTORE;
  533.  
  534.   Spells[S_CURE].powerdrain = 20;
  535.   Spells[S_CURE].id = S_CURE;
  536.  
  537.   Spells[S_TRUESIGHT].powerdrain = 20;
  538.   Spells[S_TRUESIGHT].id = S_TRUESIGHT;
  539.  
  540.   Spells[S_HELLFIRE].powerdrain = 90;
  541.   Spells[S_HELLFIRE].id = S_HELLFIRE;
  542.  
  543.   Spells[S_KNOWLEDGE].powerdrain = 10;
  544.   Spells[S_KNOWLEDGE].id = S_KNOWLEDGE;
  545.  
  546.   Spells[S_HERO].powerdrain = 20;
  547.   Spells[S_HERO].id = S_HERO;
  548.  
  549.   Spells[S_RETURN].powerdrain = 10;
  550.   Spells[S_RETURN].id = S_RETURN;
  551.  
  552.   Spells[S_DESECRATE].powerdrain = 50;
  553.   Spells[S_DESECRATE].id = S_DESECRATE;
  554.  
  555.   Spells[S_HASTE].powerdrain = 15;
  556.   Spells[S_HASTE].id = S_HASTE;
  557.  
  558.   Spells[S_SUMMON].powerdrain = 20;
  559.   Spells[S_SUMMON].id = S_SUMMON;
  560.  
  561.   Spells[S_SANCTUARY].powerdrain = 75;
  562.   Spells[S_SANCTUARY].id = S_SANCTUARY;
  563.  
  564.   Spells[S_ACCURACY].powerdrain = 20;
  565.   Spells[S_ACCURACY].id = S_ACCURACY;
  566.  
  567.   Spells[S_RITUAL].powerdrain = 50;
  568.   Spells[S_RITUAL].id = S_RITUAL;
  569.  
  570.   Spells[S_APPORT].powerdrain = 15;
  571.   Spells[S_APPORT].id = S_APPORT;
  572.  
  573.   Spells[S_SHADOWFORM].powerdrain = 50;
  574.   Spells[S_SHADOWFORM].id = S_SHADOWFORM;
  575.  
  576.   Spells[S_ALERT].powerdrain = 15;
  577.   Spells[S_ALERT].id = S_ALERT;
  578.  
  579.   Spells[S_REGENERATE].powerdrain = 20;
  580.   Spells[S_REGENERATE].id = S_REGENERATE;
  581.  
  582.   Spells[S_SANCTIFY].powerdrain = 75;
  583.   Spells[S_SANCTIFY].id = S_SANCTIFY;
  584.  
  585.   Spells[S_CLAIRVOYANCE].powerdrain = 10;
  586.   Spells[S_CLAIRVOYANCE].id = S_CLAIRVOYANCE;
  587.  
  588.   Spells[S_DRAIN].powerdrain = 40;
  589.   Spells[S_DRAIN].id = S_DRAIN;
  590.  
  591.   Spells[S_LEVITATE].powerdrain = 25;
  592.   Spells[S_LEVITATE].id = S_LEVITATE;
  593.  
  594.   Spells[S_POLYMORPH].powerdrain = 30;
  595.   Spells[S_POLYMORPH].id = S_POLYMORPH;
  596.  
  597.   Spells[S_FEAR].powerdrain = 10;
  598.   Spells[S_FEAR].id = S_FEAR;
  599.  
  600.   Spells[S_WISH].powerdrain = 100;
  601.   Spells[S_WISH].id = S_WISH;
  602.  
  603. }
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610. void cast_spell(spell)
  611. int spell;
  612. {
  613.   switch(spell) {
  614.   case S_MON_DET:s_mondet();
  615.     break;
  616.   case S_OBJ_DET:s_objdet();
  617.     break;
  618.   case S_IDENTIFY:s_identify();
  619.     break;
  620.   case S_FIREBOLT:s_firebolt();
  621.     break;
  622.   case S_SLEEP:s_sleep();
  623.     break;
  624.   case S_LBALL:s_lball();
  625.     break;
  626.   case S_TELEPORT:s_teleport();
  627.     break;
  628.   case S_DISRUPT:s_disrupt();
  629.     break;
  630.   case S_DISINTEGRATE:s_disintegrate();
  631.     break;
  632.   case S_MISSILE:s_missile();
  633.     break;
  634.   case S_HEAL:s_heal();
  635.     break;
  636.   case S_DISPEL:s_dispel();
  637.     break;
  638.   case S_BREATHE:s_breathe();
  639.     break;
  640.   case S_INVISIBLE:s_invisible();
  641.     break;
  642.   case S_WARP:s_warp();
  643.     break;
  644.   case S_ENCHANT:s_enchant();
  645.     break;
  646.   case S_BLESS:s_bless();
  647.     break;
  648.   case S_RESTORE:s_restore();
  649.     break;
  650.   case S_CURE:s_cure();
  651.     break;
  652.   case S_TRUESIGHT:s_truesight();
  653.     break;
  654.   case S_HELLFIRE:s_hellfire();
  655.     break;
  656.   case S_KNOWLEDGE:s_knowledge();
  657.     break;
  658.   case S_HERO:s_hero();
  659.     break;
  660.   case S_RETURN:s_return();
  661.     break;
  662.   case S_DESECRATE:s_desecrate();
  663.     break;
  664.   case S_HASTE:s_haste();
  665.     break;
  666.   case S_SUMMON:s_summon();
  667.     break;
  668.   case S_SANCTUARY:s_sanctuary();
  669.     break;
  670.   case S_ACCURACY:s_accuracy();
  671.     break;
  672.   case S_RITUAL:s_ritual();
  673.     break;
  674.   case S_APPORT:s_apport();
  675.     break;
  676.   case S_SHADOWFORM:s_shadowform();
  677.     break;
  678.   case S_ALERT:s_alert();
  679.     break;
  680.   case S_REGENERATE:s_regenerate();
  681.     break;
  682.   case S_SANCTIFY:s_sanctify();
  683.     break;
  684.   case S_CLAIRVOYANCE:s_clairvoyance();
  685.     break;
  686.   case S_DRAIN:s_drain();
  687.     break;
  688.   case S_LEVITATE:s_levitate();
  689.     break;
  690.   case S_FEAR:s_fear();
  691.     break;
  692.   case S_POLYMORPH:s_polymorph();
  693.     break;
  694.   case S_WISH:s_wish();
  695.     break;
  696.   default: mprint("Your odd spell fizzles with a small 'sput'.");
  697.     break;
  698.   }
  699. }
  700.  
  701.  
  702.  
  703.  
  704.  
  705. int spellparse()
  706. {
  707.   int spell= -3,place=0;
  708.   char byte,prefix[80];
  709.  
  710.   prefix[0]=0;
  711.  
  712.   do {
  713.     byte = mgetc();
  714.     if ((byte >= 'A') && (byte <= 'Z')) {
  715.       maddch(byte+'a'-'A');
  716.       prefix[place] = byte+'a'-'A';
  717.       prefix[place+1] = 0;
  718.       place++;
  719.     }
  720.     else if ((byte == ' ') || ((byte >= 'a') && (byte <= 'z'))) {
  721.       maddch(byte);
  722.       prefix[place] = byte;
  723.       prefix[place+1] = 0;
  724.       place++;
  725.     }
  726.     else if ((byte == 8) || (byte == 127)) { /* ^h or delete */ 
  727.       prefix[place]=0;
  728.       if (place > 0) {
  729.     place--;
  730.     dobackspace();
  731.       }
  732.     }
  733.     else if (byte == '?') {
  734.       maddch(byte);
  735.       expandspellabbrevs(prefix);
  736.       dobackspace();
  737.     }
  738.     else if (byte == '\n')
  739.       spell = expandspell(prefix);
  740.     else if (byte == ESCAPE)
  741.       spell = ABORT;
  742.   } while (spell == -3);
  743.   xredraw();
  744.   return(spell);
  745. }
  746.  
  747. void expandspellabbrevs(prefix)
  748. char prefix[80];
  749. {
  750.   int i,printed=FALSE;
  751.   
  752.   menuclear();
  753.   menuprint("\nPossible Spells:\n");
  754.   for (i=0;i<NUMSPELLS;i++)
  755.     if (Spells[i].known && strprefix(prefix,spellid(i))) {
  756.       menuspellprint(i);
  757.       printed = TRUE;
  758.     }
  759.   if (! printed)
  760.     menuprint("\nNo spells match that prefix!");
  761. }
  762.  
  763.  
  764. int expandspell(prefix)
  765. char prefix[80];
  766. {
  767.   int i,spell,matched=0;
  768.   
  769.   for (i=0;i<NUMSPELLS;i++)
  770.     if (Spells[i].known && strprefix(prefix,spellid(i))) {
  771.       spell = i;
  772.       matched++;
  773.     }
  774.   if (matched==0) {
  775.     mprint("No spells match that prefix!");
  776.     return(-2);
  777.   }
  778.   else if (matched > 1) {
  779.     mprint("That is an ambiguous abbreviation!");
  780.     return(-2);
  781.   }
  782.   else return(spell);
  783. }
  784.  
  785.